<!DOCTYPE html>



  


<html class="theme-next muse use-motion" lang>
<head><meta name="generator" content="Hexo 3.9.0">
  <meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="theme-color" content="#222">









<meta http-equiv="Cache-Control" content="no-transform">
<meta http-equiv="Cache-Control" content="no-siteapp">
















  
  
  <link href="/blog/lib/fancybox/source/jquery.fancybox.css?v=2.1.5" rel="stylesheet" type="text/css">







<link href="/blog/lib/font-awesome/css/font-awesome.min.css?v=4.6.2" rel="stylesheet" type="text/css">

<link href="/blog/css/main.css?v=5.1.4" rel="stylesheet" type="text/css">


  <link rel="apple-touch-icon" sizes="180x180" href="/blog/images/apple-touch-icon-next.png?v=5.1.4">


  <link rel="icon" type="image/png" sizes="32x32" href="/blog/images/favicon-32x32-next.png?v=5.1.4">


  <link rel="icon" type="image/png" sizes="16x16" href="/blog/images/favicon-16x16-next.png?v=5.1.4">


  <link rel="mask-icon" href="/blog/images/logo.svg?v=5.1.4" color="#222">





  <meta name="keywords" content="mobx,">





  <link rel="alternate" href="/blog/atom.xml" title="编程那点事" type="application/atom+xml">






<meta name="description" content="MobX简单、可扩展的状态管理 安装 安装: npm install mobx --save。 React 绑定库: npm install mobx-react --save。 要启用 ESNext 的装饰器 (可选), 参见下面。  CDN:  https://unpkg.com/mobx/lib/mobx.umd.js https://cdnjs.com/libraries/mobx">
<meta name="keywords" content="mobx">
<meta property="og:type" content="article">
<meta property="og:title" content="mobx介绍">
<meta property="og:url" content="https://lhweb.gitee.io/blog/2018/09/23/mobx介绍/index.html">
<meta property="og:site_name" content="编程那点事">
<meta property="og:description" content="MobX简单、可扩展的状态管理 安装 安装: npm install mobx --save。 React 绑定库: npm install mobx-react --save。 要启用 ESNext 的装饰器 (可选), 参见下面。  CDN:  https://unpkg.com/mobx/lib/mobx.umd.js https://cdnjs.com/libraries/mobx">
<meta property="og:locale" content="default">
<meta property="og:image" content="https://lhweb.gitee.io/blog/2018/09/23/mobx介绍/flow.png">
<meta property="og:updated_time" content="2019-10-03T05:53:45.932Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="mobx介绍">
<meta name="twitter:description" content="MobX简单、可扩展的状态管理 安装 安装: npm install mobx --save。 React 绑定库: npm install mobx-react --save。 要启用 ESNext 的装饰器 (可选), 参见下面。  CDN:  https://unpkg.com/mobx/lib/mobx.umd.js https://cdnjs.com/libraries/mobx">
<meta name="twitter:image" content="https://lhweb.gitee.io/blog/2018/09/23/mobx介绍/flow.png">



<script type="text/javascript" id="hexo.configurations">
  var NexT = window.NexT || {};
  var CONFIG = {
    root: '/blog/',
    scheme: 'Muse',
    version: '5.1.4',
    sidebar: {"position":"left","display":"post","offset":12,"b2t":false,"scrollpercent":false,"onmobile":false},
    fancybox: true,
    tabs: true,
    motion: {"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}},
    duoshuo: {
      userId: '0',
      author: 'Author'
    },
    algolia: {
      applicationID: '',
      apiKey: '',
      indexName: '',
      hits: {"per_page":10},
      labels: {"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}
    }
  };
</script>



  <link rel="canonical" href="https://lhweb.gitee.io/blog/2018/09/23/mobx介绍/">





  <title>mobx介绍 | 编程那点事</title>
  








</head>

<body itemscope itemtype="http://schema.org/WebPage" lang="default">

  
  
    
  

  <div class="container sidebar-position-left page-post-detail">
    <div class="headband"></div>

    <header id="header" class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-wrapper">
  <div class="site-meta ">
    

    <div class="custom-logo-site-title">
      <a href="/blog/" class="brand" rel="start">
        <span class="logo-line-before"><i></i></span>
        <span class="site-title">编程那点事</span>
        <span class="logo-line-after"><i></i></span>
      </a>
    </div>
      
        <p class="site-subtitle"></p>
      
  </div>

  <div class="site-nav-toggle">
    <button>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
    </button>
  </div>
</div>

<nav class="site-nav">
  

  
    <ul id="menu" class="menu">
      
        
        <li class="menu-item menu-item-home">
          <a href="/blog/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-home"></i> <br>
            
            Home
          </a>
        </li>
      
        
        <li class="menu-item menu-item-archives">
          <a href="/blog/archives/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-archive"></i> <br>
            
            Archives
          </a>
        </li>
      

      
    </ul>
  

  
</nav>



 </div>
    </header>

    <main id="main" class="main">
      <div class="main-inner">
        <div class="content-wrap">
          <div id="content" class="content">
            

  <div id="posts" class="posts-expand">
    

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="https://lhweb.gitee.io/blog/blog/2018/09/23/mobx介绍/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="lhweb">
      <meta itemprop="description" content>
      <meta itemprop="image" content="/blog/images/avatar.gif">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="编程那点事">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">mobx介绍</h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">Posted on</span>
              
              <time title="Post created" itemprop="dateCreated datePublished" datetime="2018-09-23T08:05:42+08:00">
                2018-09-23
              </time>
            

            

            
          </span>

          
            <span class="post-category">
            
              <span class="post-meta-divider">|</span>
            
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              
                <span class="post-meta-item-text">In</span>
              
              
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/blog/categories/mobx/" itemprop="url" rel="index">
                    <span itemprop="name">mobx</span>
                  </a>
                </span>

                
                
              
            </span>
          

          
            
          

          
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        <h2 id="MobX"><a href="#MobX" class="headerlink" title="MobX"></a>MobX</h2><p>简单、可扩展的状态管理</p>
<h2 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h2><ul>
<li><p>安装: <code>npm install mobx --save</code>。 React 绑定库: <code>npm install mobx-react --save</code>。 要启用 ESNext 的装饰器 (可选), 参见下面。</p>
</li>
<li><p>CDN:</p>
<ul>
<li><a href="https://unpkg.com/mobx/lib/mobx.umd.js" target="_blank" rel="noopener">https://unpkg.com/mobx/lib/mobx.umd.js</a></li>
<li><a href="https://cdnjs.com/libraries/mobx" target="_blank" rel="noopener">https://cdnjs.com/libraries/mobx</a></li>
</ul>
</li>
</ul>
<h2 id="浏览器支持"><a href="#浏览器支持" class="headerlink" title="浏览器支持"></a>浏览器支持</h2><ul>
<li>MobX &gt;=5 版本运行在任何支持 ES6 proxy 的浏览器。如果运行在像 IE11、Node.js 6 以下版本或依靠与较旧的 JavaScripCore 的安卓端的 React Native 。</li>
<li>MobX 4 可以运行在任何支持 ES5 的浏览器上，而且也将进行持续地维护。MobX 4 和 5 的 API 是相同的，并且语义上也能达到相同的效果，只是 MobX 4 存在一些 局限性。</li>
</ul>
<p>小贴士: MobX 5 包的主入口点附带 ES5 代码，以便向后兼容所有构建工具。但因为 MobX 5 只能运行在现代浏览器上，所以可以考虑使用速度最快、体积最小的 ES6 构建: lib/mobx.es6.js 。例如，通过设置 webpack 的别名: resolve: { alias: { mobx: __dirname + “/node_modules/mobx/lib/mobx.es6.js” }}</p>
<h2 id="入门"><a href="#入门" class="headerlink" title="入门"></a>入门</h2><p>MobX 是一个经过战火洗礼的库，它通过透明的函数响应式编程(transparently applying functional reactive programming - TFRP)使得状态管理变得简单和可扩展。MobX背后的哲学很简单:</p>
<p>任何源自应用状态的东西都应该自动地获得。</p>
<p>其中包括UI、数据序列化、服务器通讯，等等。<br><img src="/blog/2018/09/23/mobx介绍/flow.png" alt><br>React 和 MobX 是一对强力组合。React 通过提供机制把应用状态转换为可渲染组件树并对其进行渲染。而MobX提供机制来存储和更新应用状态供 React 使用。</p>
<p>对于应用开发中的常见问题，React 和 MobX 都提供了最优和独特的解决方案。React 提供了优化UI渲染的机制， 这种机制就是通过使用虚拟DOM来减少昂贵的DOM变化的数量。MobX 提供了优化应用状态与 React 组件同步的机制，这种机制就是使用响应式虚拟依赖状态图表，它只有在真正需要的时候才更新并且永远保持是最新的。</p>
<h2 id="核心概念"><a href="#核心概念" class="headerlink" title="核心概念"></a>核心概念</h2><p>MobX 的核心概念不多。</p>
<h3 id="Observable-state-可观察的状态"><a href="#Observable-state-可观察的状态" class="headerlink" title="Observable state(可观察的状态)"></a>Observable state(可观察的状态)</h3><p>MobX 为现有的数据结构(如对象，数组和类实例)添加了可观察的功能。 通过使用 @observable 装饰器(ES.Next)来给你的类属性添加注解就可以简单地完成这一切。<br><figure class="highlight coffeescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> &#123; observable &#125; <span class="keyword">from</span> <span class="string">"mobx"</span>;</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Todo</span> &#123;</span></span><br><span class="line">    id = Math.random();</span><br><span class="line">    @observable title = <span class="string">""</span>;</span><br><span class="line">    @observable finished = <span class="literal">false</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>使用 observable 很像把对象的属性变成excel的单元格。 但和单元格不同的是，这些值不只是原始值，还可以是引用值，比如对象和数组。</p>
<p>如果你的环境不支持装饰器语法，也不必担心。 你可以点击这里查看如何进行设置。 或者你可以直接跳过设置，因为 MobX 可以通过 decorate 工具在不支持装饰器语法的情况加使用。 尽管如此，多数 MobX 用户更喜欢装饰器语法，因为它更简洁。</p>
<p>例如，上面一段代码的ES5版本应该是这样:<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> &#123; decorate, observable &#125; <span class="keyword">from</span> <span class="string">"mobx"</span>;</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Todo</span> </span>&#123;</span><br><span class="line">    id = <span class="built_in">Math</span>.random();</span><br><span class="line">    title = <span class="string">""</span>;</span><br><span class="line">    finished = <span class="literal">false</span>;</span><br><span class="line">&#125;</span><br><span class="line">decorate(Todo, &#123;</span><br><span class="line">    title: observable,</span><br><span class="line">    finished: observable</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure></p>
<h3 id="Computed-values-计算值"><a href="#Computed-values-计算值" class="headerlink" title="Computed values(计算值)"></a>Computed values(计算值)</h3><p>使用 MobX， 你可以定义在相关数据发生变化时自动更新的值。 通过@computed 装饰器或者利用 (extend)Observable 时调用 的getter / setter 函数来进行使用。(当然，这里也可以再次使用 decorate 来替代 @ 语法)。<br><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">TodoList</span> </span>&#123;</span><br><span class="line">    <span class="meta">@observable</span> todos = [];</span><br><span class="line">    <span class="meta">@computed</span> <span class="keyword">get</span> unfinishedTodoCount() &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">this</span>.todos.filter(todo =&gt; !todo.finished).length;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>当添加了一个新的todo或者某个todo的 finished 属性发生变化时，MobX 会确保 unfinishedTodoCount 自动更新。 像这样的计算可以类似于 MS Excel 这样电子表格程序中的公式。每当只有在需要它们的时候，它们才会自动更新。</p>
<h3 id="Reactions-反应"><a href="#Reactions-反应" class="headerlink" title="Reactions(反应)"></a>Reactions(反应)</h3><p>Reactions 和计算值很像，但它不是产生一个新的值，而是会产生一些副作用，比如打印到控制台、网络请求、递增地更新 React 组件树以修补DOM、等等。 简而言之，reactions 在 响应式编程和命令式编程之间建立沟通的桥梁。</p>
<h4 id="React-组件"><a href="#React-组件" class="headerlink" title="React 组件"></a>React 组件</h4><p>如果你用 React 的话，可以把你的(无状态函数)组件变成响应式组件，方法是在组件上添加 observer 函数/ 装饰器. observer由 mobx-react 包提供的。<br><figure class="highlight scala"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> <span class="type">React</span>, &#123;<span class="type">Component</span>&#125; from <span class="symbol">'reac</span>t';</span><br><span class="line"><span class="keyword">import</span> <span class="type">ReactDOM</span> from <span class="symbol">'react</span>-dom';</span><br><span class="line"><span class="keyword">import</span> &#123;observer&#125; from <span class="symbol">'mobx</span>-react';</span><br><span class="line"></span><br><span class="line"><span class="meta">@observer</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">TodoListView</span> <span class="keyword">extends</span> <span class="title">Component</span> </span>&#123;</span><br><span class="line">    render() &#123;</span><br><span class="line">        <span class="keyword">return</span> &lt;div&gt;</span><br><span class="line">            &lt;ul&gt;</span><br><span class="line">                &#123;<span class="keyword">this</span>.props.todoList.todos.map(todo =&gt;</span><br><span class="line">                    &lt;<span class="type">TodoView</span> todo=&#123;todo&#125; key=&#123;todo.id&#125; /&gt;</span><br><span class="line">                )&#125;</span><br><span class="line">            &lt;/ul&gt;</span><br><span class="line">            <span class="type">Tasks</span> left: &#123;<span class="keyword">this</span>.props.todoList.unfinishedTodoCount&#125;</span><br><span class="line">        &lt;/div&gt;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">const <span class="type">TodoView</span> = observer((&#123;todo&#125;) =&gt;</span><br><span class="line">    &lt;li&gt;</span><br><span class="line">        &lt;input</span><br><span class="line">            <span class="class"><span class="keyword">type</span></span>=<span class="string">"checkbox"</span></span><br><span class="line">            checked=&#123;todo.finished&#125;</span><br><span class="line">            onClick=&#123;() =&gt; todo.finished = !todo.finished&#125;</span><br><span class="line">        /&gt;&#123;todo.title&#125;</span><br><span class="line">    &lt;/li&gt;</span><br><span class="line">)</span><br><span class="line"></span><br><span class="line">const store = <span class="keyword">new</span> <span class="type">TodoList</span>();</span><br><span class="line"><span class="type">ReactDOM</span>.render(&lt;<span class="type">TodoListView</span> todoList=&#123;store&#125; /&gt;, document.getElementById(<span class="symbol">'moun</span>t'));</span><br></pre></td></tr></table></figure></p>
<p>observer 会将 React (函数)组件转换为它们需要渲染的数据的衍生。 使用 MobX 时没有所谓的智能和无脑组件。 所有的组件都会以巧妙的方式进行渲染，而只需要一种简单无脑的方式来定义它们。MobX 会确保组件总是在需要的时重新渲染，但仅此而已。所以上面例子中的 onClick 处理方法会强制对应的 TodoView 进行渲染，如果未完成任务的数量(unfinishedTodoCount)已经改变，它将导致 TodoListView 进行渲染。 可是，如果移除 Tasks left 这行代码(或者将它放到另一个组件中)，当点击 checkbox 的时候 TodoListView 就不再重新渲染。你可以在 JSFiddle 中自己动手来验证这点。</p>
<h4 id="自定义-reactions"><a href="#自定义-reactions" class="headerlink" title="自定义 reactions"></a>自定义 reactions</h4><p>使用autorun、reaction 和 when 函数即可简单的创建自定义 reactions，以满足你的具体场景。</p>
<p>例如，每当 unfinishedTodoCount 的数量发生变化时，下面的 autorun 会打印日志消息:<br><figure class="highlight coffeescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">autorun(<span class="function"><span class="params">()</span> =&gt;</span> &#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">"Tasks left: "</span> + todos.unfinishedTodoCount)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure></p>
<h3 id="MobX-会对什么作出响应"><a href="#MobX-会对什么作出响应" class="headerlink" title="MobX 会对什么作出响应?"></a>MobX 会对什么作出响应?</h3><p>为什么每次 unfinishedTodoCount 变化时都会打印一条新消息？答案就是下面这条经验法则:</p>
<p>MobX 会对在执行跟踪函数期间读取的任何现有的可观察属性做出反应。</p>
<p>想深入了解 MobX 是如何知道需要对哪个可观察属性进行响应，请查阅 理解 MobX 对什么有反应。</p>
<h3 id="Actions-动作"><a href="#Actions-动作" class="headerlink" title="Actions(动作)"></a>Actions(动作)</h3><p>不同于 flux 系的一些框架，MobX 对于如何处理用户事件是完全开明的。</p>
<ul>
<li>可以用类似 Flux 的方式完成</li>
<li>或者使用 RxJS 来处理事件</li>
<li>或者用最直观、最简单的方式来处理事件，正如上面演示所用的 onClick<br>最后全部归纳为: 状态应该以某种方式来更新。</li>
</ul>
<p>当状态更新后，MobX 会以一种高效且无障碍的方式处理好剩下的事情。像下面如此简单的语句，已经足够用来自动更新用户界面了。</p>
<p>从技术上层面来讲，并不需要触发事件、调用分派程序或者类似的工作。归根究底 React 组件只是状态的华丽展示，而状态的衍生由 MobX 来管理。</p>
<figure class="highlight haxe"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">store.todos.push(</span><br><span class="line">    <span class="keyword">new</span> <span class="type">Todo</span>(<span class="string">"Get Coffee"</span>),</span><br><span class="line">    <span class="keyword">new</span> <span class="type">Todo</span>(<span class="string">"Write simpler code"</span>)</span><br><span class="line">);</span><br><span class="line">store.todos[<span class="number">0</span>].finished = <span class="literal">true</span>;</span><br></pre></td></tr></table></figure>
<p>尽管如此，MobX 还是提供了 actions 这个可选的内置概念。 如果你现在就想要了解如何编写 actions，请阅读 Actions 章节。很简单！ 使用 actions 是有优势的: 它们可以帮助你把代码组织的更好，还能在状态何时何地应该被修改这个问题上帮助你做出明智的决定。</p>
<h2 id="MobX-简单且可扩展"><a href="#MobX-简单且可扩展" class="headerlink" title="MobX: 简单且可扩展"></a>MobX: 简单且可扩展</h2><p>MobX 是状态管理库中侵入性最小的之一。这使得 MobX的方法不但简单，而且可扩展性也非常好:</p>
<h3 id="使用类和真正的引用"><a href="#使用类和真正的引用" class="headerlink" title="使用类和真正的引用"></a>使用类和真正的引用</h3><p>使用 MobX 不需要使数据标准化。这使得库十分适合那些异常复杂的领域模型(以 Mendix 为例: 一个应用中有大约500个领域类)。</p>
<h3 id="保证参照完整性"><a href="#保证参照完整性" class="headerlink" title="保证参照完整性"></a>保证参照完整性</h3><p>因为数据不需要标准化，所以 MobX 会自动跟踪状态和衍生之间的关系，你可以免费获得参照完整性。渲染通过三级间接寻址访问的数据？</p>
<p>没有问题，MobX 会跟踪它们，一旦其中一个引用发生了变化，就会重新渲染。作为回报，陈年的老bug已不复存在。作为一个程序员，你可能记不住修改的一些数据可能会影响到的某个角落里看起来毫不相关的组件，但 MobX 不会。</p>
<h3 id="更简单的-actions-更便于维护"><a href="#更简单的-actions-更便于维护" class="headerlink" title="更简单的 actions 更便于维护"></a>更简单的 actions 更便于维护</h3><p>正如上面所演示的，使用 MobX 修改状态是非常简单的。你只需简单的写出你的目的。MobX 会替你处理好剩下的事情。</p>
<h3 id="细粒度的可观测性是高效的"><a href="#细粒度的可观测性是高效的" class="headerlink" title="细粒度的可观测性是高效的"></a>细粒度的可观测性是高效的</h3><p>MobX 构建应用中所有衍生的图形，以找到保持最新状态所需的重新计算的最少次数。“衍生一切”或许听上去开销很昂贵，但 MobX 构建虚拟衍生图以保持衍生与状态同步所需的重计算的数量最小化。</p>
<p>事实上，在 Mendix 测试 MobX 时我们发现使用这个库跟踪代码中的关系通常会更有效，而不是通过使用手写事件或基于容器组件的“智能”选择器来推送更改。</p>
<p>简单来说，是因为 MobX 会在数据上建立更细粒度的“监听器”，而不是通过程序来控制。</p>
<p>其次, MobX 看到衍生之间的因果关系，因此它可以为衍生排序，使得衍生不会运行多次或引入缺陷。</p>
<p>想了解这是如何工作的？ 请参见 深入剖析 MobX。</p>
<h3 id="易操作性"><a href="#易操作性" class="headerlink" title="易操作性"></a>易操作性</h3><p>MobX 使用原生 javascript 。由于它的侵入性不强，它可以和绝大部分 javascript 库共同使用，而不需要特定的 MobX 风格库。</p>
<p>所以你可以继续使用你的路由，数据获取和工具库，比如react-router、 director、 superagent、 lodash，等等。</p>
<p>出于同样的原因，你可以在服务器端和客户端使用它，也可以在 react-native 这样的同构应用中使用。</p>
<p>结论就是: 相比其它状态管理解决方案，当使用 MobX 时通常只需学习更少的新概念。</p>

      
    </div>
    
    
    

    

    

    

    <footer class="post-footer">
      
        <div class="post-tags">
          
            <a href="/blog/tags/mobx/" rel="tag"># mobx</a>
          
        </div>
      

      
      
      

      
        <div class="post-nav">
          <div class="post-nav-next post-nav-item">
            
              <a href="/blog/2018/09/23/React-with-TypeScript-系列-五-Flux/" rel="next" title="React with TypeScript 系列(五) --Flux">
                <i class="fa fa-chevron-left"></i> React with TypeScript 系列(五) --Flux
              </a>
            
          </div>

          <span class="post-nav-divider"></span>

          <div class="post-nav-prev post-nav-item">
            
              <a href="/blog/2018/09/23/typescript-react-mobx的todo实例教程/" rel="prev" title="typescript+react+mobx的todo实例教程">
                typescript+react+mobx的todo实例教程 <i class="fa fa-chevron-right"></i>
              </a>
            
          </div>
        </div>
      

      
      
    </footer>
  </div>
  
  
  
  </article>



    <div class="post-spread">
      
    </div>
  </div>


          </div>
          


          

  



        </div>
        
          
  
  <div class="sidebar-toggle">
    <div class="sidebar-toggle-line-wrap">
      <span class="sidebar-toggle-line sidebar-toggle-line-first"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-middle"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-last"></span>
    </div>
  </div>

  <aside id="sidebar" class="sidebar">
    
    <div class="sidebar-inner">

      

      
        <ul class="sidebar-nav motion-element">
          <li class="sidebar-nav-toc sidebar-nav-active" data-target="post-toc-wrap">
            Table of Contents
          </li>
          <li class="sidebar-nav-overview" data-target="site-overview-wrap">
            Overview
          </li>
        </ul>
      

      <section class="site-overview-wrap sidebar-panel">
        <div class="site-overview">
          <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
            
              <p class="site-author-name" itemprop="name">lhweb</p>
              <p class="site-description motion-element" itemprop="description"></p>
          </div>

          <nav class="site-state motion-element">

            
              <div class="site-state-item site-state-posts">
              
                <a href="/blog/archives/">
              
                  <span class="site-state-item-count">39</span>
                  <span class="site-state-item-name">posts</span>
                </a>
              </div>
            

            
              
              
              <div class="site-state-item site-state-categories">
                <a href="/blog/categories/index.html">
                  <span class="site-state-item-count">6</span>
                  <span class="site-state-item-name">categories</span>
                </a>
              </div>
            

            
              
              
              <div class="site-state-item site-state-tags">
                <a href="/blog/tags/index.html">
                  <span class="site-state-item-count">25</span>
                  <span class="site-state-item-name">tags</span>
                </a>
              </div>
            

          </nav>

          
            <div class="feed-link motion-element">
              <a href="/blog/atom.xml" rel="alternate">
                <i class="fa fa-rss"></i>
                RSS
              </a>
            </div>
          

          

          
          

          
          

          

        </div>
      </section>

      
      <!--noindex-->
        <section class="post-toc-wrap motion-element sidebar-panel sidebar-panel-active">
          <div class="post-toc">

            
              
            

            
              <div class="post-toc-content"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#MobX"><span class="nav-number">1.</span> <span class="nav-text">MobX</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#安装"><span class="nav-number">2.</span> <span class="nav-text">安装</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#浏览器支持"><span class="nav-number">3.</span> <span class="nav-text">浏览器支持</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#入门"><span class="nav-number">4.</span> <span class="nav-text">入门</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#核心概念"><span class="nav-number">5.</span> <span class="nav-text">核心概念</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#Observable-state-可观察的状态"><span class="nav-number">5.1.</span> <span class="nav-text">Observable state(可观察的状态)</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Computed-values-计算值"><span class="nav-number">5.2.</span> <span class="nav-text">Computed values(计算值)</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Reactions-反应"><span class="nav-number">5.3.</span> <span class="nav-text">Reactions(反应)</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#React-组件"><span class="nav-number">5.3.1.</span> <span class="nav-text">React 组件</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#自定义-reactions"><span class="nav-number">5.3.2.</span> <span class="nav-text">自定义 reactions</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#MobX-会对什么作出响应"><span class="nav-number">5.4.</span> <span class="nav-text">MobX 会对什么作出响应?</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Actions-动作"><span class="nav-number">5.5.</span> <span class="nav-text">Actions(动作)</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#MobX-简单且可扩展"><span class="nav-number">6.</span> <span class="nav-text">MobX: 简单且可扩展</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#使用类和真正的引用"><span class="nav-number">6.1.</span> <span class="nav-text">使用类和真正的引用</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#保证参照完整性"><span class="nav-number">6.2.</span> <span class="nav-text">保证参照完整性</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#更简单的-actions-更便于维护"><span class="nav-number">6.3.</span> <span class="nav-text">更简单的 actions 更便于维护</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#细粒度的可观测性是高效的"><span class="nav-number">6.4.</span> <span class="nav-text">细粒度的可观测性是高效的</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#易操作性"><span class="nav-number">6.5.</span> <span class="nav-text">易操作性</span></a></li></ol></li></ol></div>
            

          </div>
        </section>
      <!--/noindex-->
      

      

    </div>
  </aside>


        
      </div>
    </main>

    <footer id="footer" class="footer">
      <div class="footer-inner">
        <div class="copyright">&copy; <span itemprop="copyrightYear">2019</span>
  <span class="with-love">
    <i class="fa fa-user"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">lhweb</span>

  
</div>


  <div class="powered-by">Powered by <a class="theme-link" target="_blank" href="https://hexo.io">Hexo</a></div>



  <span class="post-meta-divider">|</span>



  <div class="theme-info">Theme &mdash; <a class="theme-link" target="_blank" href="https://github.com/iissnan/hexo-theme-next">NexT.Muse</a> v5.1.4</div>




        







        
      </div>
    </footer>

    
      <div class="back-to-top">
        <i class="fa fa-arrow-up"></i>
        
      </div>
    

    

  </div>

  

<script type="text/javascript">
  if (Object.prototype.toString.call(window.Promise) !== '[object Function]') {
    window.Promise = null;
  }
</script>









  












  
  
    <script type="text/javascript" src="/blog/lib/jquery/index.js?v=2.1.3"></script>
  

  
  
    <script type="text/javascript" src="/blog/lib/fastclick/lib/fastclick.min.js?v=1.0.6"></script>
  

  
  
    <script type="text/javascript" src="/blog/lib/jquery_lazyload/jquery.lazyload.js?v=1.9.7"></script>
  

  
  
    <script type="text/javascript" src="/blog/lib/velocity/velocity.min.js?v=1.2.1"></script>
  

  
  
    <script type="text/javascript" src="/blog/lib/velocity/velocity.ui.min.js?v=1.2.1"></script>
  

  
  
    <script type="text/javascript" src="/blog/lib/fancybox/source/jquery.fancybox.pack.js?v=2.1.5"></script>
  


  


  <script type="text/javascript" src="/blog/js/src/utils.js?v=5.1.4"></script>

  <script type="text/javascript" src="/blog/js/src/motion.js?v=5.1.4"></script>



  
  

  
  <script type="text/javascript" src="/blog/js/src/scrollspy.js?v=5.1.4"></script>
<script type="text/javascript" src="/blog/js/src/post-details.js?v=5.1.4"></script>



  


  <script type="text/javascript" src="/blog/js/src/bootstrap.js?v=5.1.4"></script>



  


  




	





  





  












  





  

  

  

  
  

  

  

  

</body>
</html>
